package com.bob.web.dao;

import com.bob.web.common.constant.Page;
import com.bob.web.entity.BaseIncIdEntity;
import com.mongodb.WriteResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 名称: BaseMongoDaoSupport<br>
 * 描述:<br>
 * 类型: JAVA<br>
 * 最近修改时间:2017/7/12 14:47<br>
 *
 * @author BoYangsh
 * @version [版本号, V1.0]
 * @since 2017/7/12 14:47
 */
public class BaseMongoDaoSupport {

	@Autowired
	private MongoTemplate mongoTemplate;

	/**
	 * 给实体添加主键
	 * @param entity
	 * @return
	 */
	private Number incrId(BaseIncIdEntity entity) {
		String sequenceId = entity.getClass().getName();
		Query query = new Query(Criteria.where("_id").is(sequenceId));
		Update update = new Update().inc("value", 1);
		Map<String, Object> result = mongoTemplate.findAndModify(
				query,
				update,
				new FindAndModifyOptions().returnNew(true),
				HashMap.class, "IdSeqence");
		if (result == null) {
			result = new HashMap();
			result.put("_id", sequenceId);
			if (entity.getId() instanceof Long) {
				result.put("value", 1L);
			} else {
				result.put("value", 1);
			}
			mongoTemplate.insert(result, "IdSeqence");
		}
		Number v = (Number) result.get("value");
		return v;
	}

	protected void insert(BaseIncIdEntity obj) {
		obj.setId(incrId(obj));
		mongoTemplate.insert(obj);
	}

	protected <T> List<T> find(Query query, Class<T> entityClass) {
		return mongoTemplate.find(query, entityClass);
	}

	protected <T> List<T> findAll(Class<T> entityClass) {
		return mongoTemplate.find(new Query(), entityClass);
	}

	protected <T> T findAndModify (Query query, Update update, Class<T> entityClass){
		return mongoTemplate.findAndModify(query, update, entityClass);
	}


	protected <T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass) {
		return mongoTemplate.findAndModify(query, update, options, entityClass);
	}

	protected <T> T findOne(Query query, Class<T> entityClass){
		return mongoTemplate.findOne(query, entityClass);
	}

	protected WriteResult remove(Object obj) {
		return mongoTemplate.remove(obj);
	}

	protected <T> WriteResult removeById(Object objId, Class<T> entityClass) {
		Query query = Query.query(Criteria.where("_id").is(objId));
		return mongoTemplate.remove(query, entityClass);
	}

	protected <T> WriteResult remove(Query query, Class<T> entityClass) {
		return mongoTemplate.remove(query, entityClass);
	}

	protected <T> void findPage(Query query, Page<T> page, Class<T> entityClass) {
		page.setTotal(mongoTemplate.count(query, entityClass));
		query.skip(page.getIndex()).limit(page.getPageSize());
		List<T> list =  mongoTemplate.find(query, entityClass);
		page.setResult(list);
	}

	protected void includes(Query query, String...fields) {
		for(String field : fields) {
			query.fields().include(field);
		}
	}
}



